import { SyncOutlined, LoadingOutlined } from '@ant-design/icons'
import { ClassNames } from '@emotion/react'
import { Popconfirm, Tooltip, Button, Tag, Badge } from 'antd'
import c from 'classnames'
import { Actionable } from '@/desktop/components'
import  defaultAvatar  from '@/desktop/assets/avatar.jpg'
import { flexCenter, ellipsis, colors } from '@/desktop/styles'
import { useStreams } from '@/lib/utils'
import services from '@/services'
import type { QywxStatusInfo, QywxInfo } from '@/services/qywxs'
import { Status } from '@/services/qywxs'

interface Actions {
  focus: (wxid: string) => void
  cancelFocus: () => void
  logout: (wxid: string) => void
  startTransfer: (qywx: QywxInfo) => void
  startChoose: (wxid: string) => void
}

export function QywxItem(
  props: {
    qywx: QywxStatusInfo
    unread?: number
    collapsed: boolean
    focused: boolean // 是否处于“多开模式”且此企业微信被选中
  } & Actions,
) {
  const { qywx, unread, collapsed, focused, ...actions } = props
  return <ClassNames>
    {({ css }) => <Tooltip
      overlayClassName={css(styles.detail)}
      title={<QywxDetail qywx={qywx} focused={focused} {...actions} />}
      placement="rightTop"
      color="white"
    >
      <div css={styles.item} className={c(collapsed && 'collapsed')}>
        <div className="item-inner">
          <QywxAvatar qywx={qywx} unread={unread} focused={focused} {...actions} />
          <div css={styles.info}>
            <div className="qywx-name">{qywx.friendlyName}</div>
            <div className="corp-name">{qywx.corpname}</div>
          </div>
        </div>
      </div>
    </Tooltip>}
  </ClassNames>
}

function QywxAvatar({
  qywx,
  unread,
  focused,
  focus,
  cancelFocus,
}: {
  qywx: QywxStatusInfo
  unread?: number
  focused: boolean
} & Actions) {
  const preparing = qywx.status === Status.Preparing

  // 自行根据 hover 状态判断要不要显示“只看此企微”
  // 因为 Tooltip 默认行为会在 focus 状态变化时误触发显示（尽管 item 并没有被 hover）
  const [hovering, setHovering] = useState(false)
  const hoverTimeoutIdRef = useRef<NodeJS.Timeout | null>(null)
  function onHover() {
    if (hoverTimeoutIdRef.current) clearTimeout(hoverTimeoutIdRef.current)
    hoverTimeoutIdRef.current = setTimeout(() => setHovering(true), 200)
  }
  function onNotHover() {
    if (hoverTimeoutIdRef.current) clearTimeout(hoverTimeoutIdRef.current)
    setHovering(false)
  }

  const avatar = <img className="avatar" src={qywx.avatar || defaultAvatar} />

  return <Tooltip
    open={!preparing && hovering}
    title={focused ? '取消只看此企微' : '只看此企微'}
    placement="topLeft"
  >
    <div
      css={styles.avatarWrap}
      className={c(focused && 'focused', preparing && 'preparing')}
      onClick={() => (focused ? cancelFocus() : focus(qywx.wxid))}
      onMouseEnter={onHover}
      onMouseLeave={onNotHover}
    >
      {preparing ? (
        <div className="preparing-icon">
          <LoadingOutlined />
        </div>
      ) : null}
      {unread === undefined ? (
        avatar
      ) : (
        <Badge count={unread} size="small">
          {avatar}
        </Badge>
      )}
    </div>
  </Tooltip>
}

function QywxDetail({
  qywx,
  focused,
  focus,
  cancelFocus,
  logout,
  startTransfer,
  startChoose,
}: { qywx: QywxStatusInfo; focused: boolean } & Actions) {
  const { status } = qywx
  const preparing = qywx.status === Status.Preparing

  const [observingAccounts] = useStreams(services.auth.observing.accounts$)
  const observingAccountName = observingAccounts
    ? observingAccounts.find(acc => acc.id === qywx.accountId)?.name ?? qywx.accountId
    : ''

  const row = (label: string, value: React.ReactNode) => <div className="row">
    <label>{label}</label>
    <span>{value}</span>
  </div>

  return <>
    <section>
      <header>详细信息</header>
      {observingAccountName ? row('所属账号', observingAccountName) : null}
      {row('昵称', qywx.friendlyName)}
      {row('公司', qywx.corpname)}
      {row('wxid', qywx.wxid)}
      {row('corpid', qywx.corpid)}
      {row('hostname', qywx.hostname)}
      {row('acctid', qywx.acctid)}
      {row(
        '状态',
        <>
          {status === Status.Normal ? <Tag color="success">正常</Tag> : null}
          {status === Status.Preparing ? (
            <Tag icon={<SyncOutlined spin />} color="processing">
              正在初始化...
            </Tag>
          ) : null}
        </>,
      )}
    </section>
    <Actionable>
      <section>
        <header>操作</header>
        <div className="actions">
          <Button size="small" onClick={() => startChoose(qywx.wxid)}>
            多选
          </Button>
          {!preparing && !focused ? (
            <Button size="small" onClick={() => focus(qywx.wxid)}>
              只看他
            </Button>
          ) : null}
          {!preparing && focused ? (
            <Button size="small" onClick={() => cancelFocus()}>
              取消“只看他”
            </Button>
          ) : null}

          <Actionable strict>
            {!preparing ? (
              <Button size="small" type="primary" onClick={() => startTransfer(qywx)}>
                转交
              </Button>
            ) : null}
          </Actionable>

          <ClassNames>
            {({ css }) => <Popconfirm
              overlayClassName={css(styles.logoutConfirm)}
              onConfirm={() => logout(qywx.wxid)}
              title="确定要登出此企业微信吗？"
            >
              <Button size="small" type="primary">
                登出
              </Button>
            </Popconfirm>}
          </ClassNames>
        </div>
      </section>
    </Actionable>
  </>
}

const styles = {
  item: css`
    transition: background-color 0.2s;
    padding: 8px 0;
    &:first-of-type {
      padding-top: 0;
    }
    &:last-child {
      padding-bottom: 0;
    }
    .item-inner {
      align-items: center;
      display: flex;
      height: 50px;
      margin-left: 11px;
    }
  `,

  avatarWrap: css`
    border-radius: 11px;
    border: 2px solid transparent;
    margin-right: 6px;
    padding: 2px;
    position: relative;
    transition: border-color 0.2s;
    &.focused {
      border-color: #1890ff;
      cursor: default;
    }
    &:not(.preparing) {
      cursor: pointer;
    }
    &:not(.focused):not(.preparing):hover {
      border-color: #fafafa;
    }

    .avatar,
    .ant-badge,
    .preparing-icon {
      display: block;
      height: 42px;
      width: 42px;
      border-radius: 8px;
    }
    .preparing-icon {
      ${flexCenter};
      background-color: rgba(255, 255, 255, 0.6);
      border-radius: 8px;
      font-size: 22px;
      position: absolute;
    }
  `,

  info: css`
    cursor: default;
    flex: 1;
    overflow: hidden;
    // 5px 刚好在收起状态下遮住文字。千万不要再加大，不然收起状态，最后一个企微下会出现额外空白。
    padding-right: 5px;
    .qywx-name {
      ${ellipsis};
      color: rgba(0, 0, 0, 0.65);
      margin-bottom: 4px;
    }
    .corp-name {
      ${ellipsis};
      color: ${colors.gray};
      font-size: 12px;
    }
  `,

  detail: css`
    max-width: 300px;

    .ant-tooltip-inner {
      color: #555;
      font-size: 12px;
      padding: 16px 20px 20px;
    }

    section:not(:last-child) {
      margin-bottom: 16px;
    }

    header {
      font-weight: bold;
      margin-bottom: 4px;
    }

    .row {
      display: flex;
      padding: 2px 6px;
      align-items: baseline;
      & > label {
        color: #999;
        flex-shrink: 0;
        margin-right: 12px;
        text-align: right;
        width: 60px;
      }
      & > span {
        flex: 1;
        word-break: break-all;
        word-wrap: break-word;
      }
    }

    .actions {
      padding-top: 1px;
      button {
        margin-right: 4px;
        font-size: 12px;
      }
    }
  `,
  logoutConfirm: css`
    z-index: 1070; // 让此 popconfirm 和 tooltip 保持同样的 z-index，以免被遮挡
  `,
}
